import * as THREE from "three";

export class Circle extends THREE.Mesh<THREE.BufferGeometry, THREE.ShaderMaterial> {
    private _elapsedTime: THREE.IUniform<number>;

    constructor ( radius = 10, segments = 10, color = new THREE.Color( 0Xffffff ) ) {
        super();
        this._elapsedTime = { value: 0 };

        Object.defineProperty( this, "isCircle", {
            writable: false,
            enumerable: true,
            value: true,
        } );
        this.geometry = new THREE.PlaneGeometry(
            radius * 2,
            radius * 2,
            segments,
            segments,
        );

        this.geometry.applyMatrix4( new THREE.Matrix4().makeRotationX( -Math.PI / 2 ) );

        this.material = new THREE.ShaderMaterial( {
            // side: THREE.DoubleSide,
            transparent: true,
            // forceSinglePass: true,
            depthTest: false,
            blending: THREE.NormalBlending,
            uniforms: {
                uTime: this._elapsedTime,
                uColor: {
                    value: color
                }
            },
            vertexShader: `
            varying vec2 vUv;
            void main() {
                vUv = uv;
                gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
            }`,
            fragmentShader: `
            varying vec2 vUv;
            uniform float uTime;
            uniform vec3 uColor;
            void main(){
                vec2 center = vec2(0.5,0.5);
                float dis = distance(vUv,center);
                float p = 6.0;
                float r =  fract(dis* p - uTime)/3. + smoothstep(0.99,1.1111, fract(dis* p - uTime));
                if(dis> 0.5 ){
                    r = 0.0;
                }
                gl_FragColor = vec4(uColor,r);
            }`,
        } );
    }

    update ( delta: number ) {
        this._elapsedTime.value += delta;
    }
    dispose () {
        this.geometry.dispose();
        this.material.dispose();
    }
}